#include <mezza/tstr.h>
#include <mezza/vstr.h>
#include <mezza/str.h>
#include <mezza/int.h>
#include <mezza/lang.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

mztstr_t mztstr_new(mzsize_t lines, mzsize_t cols, mzsize_t ssize) {

	if(lines && cols && ssize) {
		mztstr_t ret;
		mzobj_t obj;
		mzsize_t i;

		/* Aloca o objeto da tabela */
		obj = (mzobj_t)malloc(sizeof(mzsize_t) + (lines * sizeof(mzvstr_t)));

		/* Coloca a informação de tamanho no objeto */
		OBJ_META(obj) = lines;

		/* Obtém ponteiro para o subobjeto */
		ret = (mztstr_t)OBJ_SUB(obj);

		/* Aloca cada linha da tabela */
		i = lines;
		ML_REPEAT_DOWN(i) {
			if(NULL == (ret[i] = mzvstr_new(cols, ssize))) {
				/* Em caso de erro, chama o desalocador de
				vetor de string para cada vstr já alocado */
				ML_REPEAT_TOEND(i, lines) mzvstr_free(ret[i]);
				/* Desaloca também o objeto da tabela */
				free(obj);
				return NULL;
			}
		}

		return ret;
	}

	return NULL;
}

mztstr_t mztstr_free(mztstr_t ts) {
    if(ts)
	{
		mzsize_t vsize;
		mzobj_t obj;

		obj = OBJ(ts);

		vsize = OBJ_META(obj);

		ML_REPEAT_DOWN(vsize) if(ts[vsize]) mzvstr_free(ts[vsize]);

		free(obj);
	}

	return NULL;
}

int mztstr_realloc(mztstr_t *ts, mzsize_t lines, mzsize_t cols) {
	mztstr_t newts;
	mzsize_t ssize;
	mzsize_t actual_tsize;

	/* Obtém o tamanho atual da tabela */
	actual_tsize	= OBJ_META(OBJ(*ts));

	if(actual_tsize != lines) {
		/* Obtém o tamanho alocado da primeira string
            Desconta o caractere extra alocado para o
            terminador nulo ('\0') */
		ssize	= OBJ_META(OBJ(*(*(*vs)))) - 1;

		/* Aloca a nova tabela de strings */
		if(NULL == (newts = mztstr_new(lines, cols, ssize))) return -1;

		/* Detecta redução de tamanho */
		if(actual_tsize > lines) {
			SWAP_INT(actual_tsize, lines);
		} else {
		/* Se a nova tabela possuir mais posições, as excedentes
		conterão linhas com strings vazias */
			mzsize_t actual_tsize_L, actual_vsize, actual_vsize_L;

			for(actual_tsize_L = actual_tsize;
				actual_tsize_L < lines;
				actual_tsize_L++) {
				    actual_vsize = OBJ_META(OBJ(*(*vs))) - 1;
                    for(actual_vsize_L = )
				}
		}

		/* Faz a cópia das strings do antigo vetor */
		ML_REPEAT_DOWN(actual_tsize) strcpy(newts[actual_tsize], (*vs)[actual_tsize]);

		/* Desaloca o antigo vetor */
		mzvstr_free(*ts);

		/* Passa o vetor para o escopo superior (retorno) */
		*ts = newts;
	}
	return 0;
}
